﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MagicCove
{
    class MagicField
    {
        private GameForm parentGameForm;
        private int[] mana;//contains the ammount of floating mana that turn (increased by tapping lands).
        private int poisonCounters; //number of poisen couters the player has

        public List<MagicCard> deck;
        public List<MagicCard> sideboard;
        public String deckName;
        public List<MagicCard> hand;
        public List<MagicCard> field;
        public List<MagicCard> graveyard;
        public List<MagicCard> exiled;
        public Player player;
        public List<MagicCard> additionalPlayers; //additional players on the field. Planeswalkers keep their current life total in defense.
        public int life;

        public bool landPlayed;
        public MagicField(String deckString) //creates a generic field. Mainly used for deck creation and analysis
        {
            createDeck(deckString, Player.P1, false);
            foreach (MagicCard mC in deck)
                mC.ParentField = this;
            hand = new List<MagicCard>();
            field = new List<MagicCard>();
            graveyard = new List<MagicCard>();
            exiled = new List<MagicCard>();
            life = 20;
            landPlayed = false;
            mana = new int[] { 0, 0, 0, 0, 0, 0 };
        }
        public MagicField(String deckString, Player owner, GameForm parentGameForm, bool enforceRules)
        {
            createDeck(deckString, owner, enforceRules);
            player = owner;
            foreach (MagicCard mC in deck)
                mC.ParentField = this;
            shuffleDeck();
            hand = new List<MagicCard>();
            field = new List<MagicCard>();
            graveyard = new List<MagicCard>();
            exiled = new List<MagicCard>();
            life = 20;
            landPlayed = false;
            mana = new int[] { 0, 0, 0, 0, 0, 0 };
            this.parentGameForm = parentGameForm;
            for (int i = 0; i < 7; i++) //Draws top card 7 times
                drawCard(0);
        }
        public MagicField(String deckString, Player owner, GameForm parentGameForm, bool enforceRules, int life)
        {
            createDeck(deckString, owner, enforceRules);
            player = owner;
            foreach (MagicCard mC in deck)
                mC.ParentField = this;
            shuffleDeck();
            hand = new List<MagicCard>();
            field = new List<MagicCard>();
            graveyard = new List<MagicCard>();
            exiled = new List<MagicCard>();
            this.life = life;
            landPlayed = false;
            mana = new int[] { 0, 0, 0, 0, 0, 0 };
            this.parentGameForm = parentGameForm;
            for (int i = 0; i < 7; i++) //Draws top card 7 times
                drawCard(0);
        }
        public void drawCard()
        {//draws top card
            drawCard(0);
        }
        public void drawCard(int n)
        {
            if (n < 0)
                throw new System.Exception("Invalid parameter in draw cards");
            else if (n < deck.Count)
            {
                hand.Add(deck[n]);
                deck[n].Location = CurrentLocation.Hand;
                deck[n].LocationGoing = CurrentLocation.Hand;
                deck.RemoveAt(n);
            }
            else if (deck.Count == 0)
                System.Windows.Forms.MessageBox.Show(player.ToString() + " lost the game.");
        }
        public MagicCard getAndRemoveDeckCard(int n)
        {
            MagicCard temp;
            if (n < deck.Count)
            {
                temp = deck[n];
                deck.RemoveAt(n);
                return temp;
            }
            else
            {
                return null;
            }
        }
        //Add a card anywhere in the deck
        public void addToDeck(int n, MagicCard cardToAdd)
        {
            if (n < deck.Count)
                deck.Insert(n, cardToAdd);
        }
        //Place card on buttom of deck
        public void addToDeckBottom(MagicCard cardToAdd)
        {
            deck.Add(cardToAdd);
        }

        #region Properties
        public String DeckName
        {
            get
            {
                return this.deckName;
            }
            set
            {
                this.deckName = value;
            }
        }
        public GameForm ParentGameForm
        {
            get
            {
                return this.parentGameForm;
            }
        }
        public int[] Mana
        {
            get
            {
                return this.mana;
            }
            set
            {
                this.mana = value;
            }
        }
        public int PoisonCounters
        {
            get
            {
                return this.poisonCounters;
            }
            set
            {
                poisonCounters = value;
            }
        }
        #endregion
        //returns number of cards left in deck
        public int cardsInDeck()
        {
            return deck.Count;
        }
        public void shuffleDeck() //randomly reorganizes all the elements in the list deck. Note: this represents a completely random shuffle, not based on any human shuffle techniques
        {
            List<MagicCard> tempShufDeck = new List<MagicCard>();
            Random rand = new Random(); //holds the random number
            int randNum;//holds the random number
            while (deck.Count > 0)
            {
                randNum = rand.Next(deck.Count - 1);//gen randNum, if necessary set to range of deck, note this should only be as big as the remaining cards in the deck
                tempShufDeck.Add(deck[randNum]);
                deck.RemoveAt(randNum);
            }
            deck = tempShufDeck;
        }
        #region Private Functions
        private void createDeck(String deckToCreate, Player owner, bool enforceRules)
        {//This assumes that deck has been stripped down to its basic form, all comment lines have been removed.
            //This will envolve a long case statement to add every card to the deck
            deck = new List<MagicCard>();
            sideboard = new List<MagicCard>();
            if (deckToCreate[0].Equals(":"))
                deckName = deckToCreate.Substring(1, deckToCreate.IndexOf("\r") - 1);//no cr or lf char (/r and /n)
            else
                deckName = "";
            deckToCreate = deckToCreate.Substring(deckToCreate.IndexOf("\n") + 1);
            String cardNameString;//will hold the name of the card desired
            int numOfCards;//number of a card that needs to be added to the deck
            while ((!deckToCreate.Equals("") && deckToCreate.Length < 9) || (deckToCreate.Length >= 9 && !deckToCreate.Substring(0, 9).Contains("Sideboard")))//while there are still cards in the deck string not placed in deck list or sideboard has not been reached
            {
                numOfCards = Convert.ToInt32(deckToCreate.Substring(0, deckToCreate.IndexOf("-")));
                if (deckToCreate.IndexOf("\n") == -1) //last card case
                {
                    cardNameString = deckToCreate.Substring(deckToCreate.IndexOf("-") + 1);
                    deckToCreate = ""; //this is the last card
                }
                else //the majority of cards
                {
                    cardNameString = deckToCreate.Substring(deckToCreate.IndexOf("-") + 1, deckToCreate.IndexOf("\r") - deckToCreate.IndexOf("-") - 1);
                    deckToCreate = deckToCreate.Substring(deckToCreate.IndexOf("\n") + 1); //remove card from the string
                }
                for (int i = 1; i <= numOfCards; i++)
                {
                    if (enforceRules)
                        deck.Add(CardDefLibrary.getCardByString(cardNameString, owner));
                    else
                        deck.Add(CardDefLibrary.getGenericCardByString(cardNameString, owner));
                }
            }
            if (deckToCreate.IndexOf("\n") == -1) //Sideboard last line
                deckToCreate = "";
            if (deckToCreate.Length >= 9 && deckToCreate.Substring(0, 9).Contains("Sideboard"))
                deckToCreate = deckToCreate.Substring(deckToCreate.IndexOf("\n") + 1);
            while (!deckToCreate.Equals("")) //finish reading deck if there is a sideboard
            {
                numOfCards = Convert.ToInt32(deckToCreate.Substring(0, deckToCreate.IndexOf("-")));
                if (deckToCreate.IndexOf("\n") == -1) //last card case
                {
                    cardNameString = deckToCreate.Substring(deckToCreate.IndexOf("-") + 1);
                    deckToCreate = ""; //this is the last card
                }
                else //the majority of cards
                {
                    cardNameString = deckToCreate.Substring(deckToCreate.IndexOf("-") + 1, deckToCreate.IndexOf("\r") - deckToCreate.IndexOf("-") - 1);
                    deckToCreate = deckToCreate.Substring(deckToCreate.IndexOf("\n") + 1); //remove card from the string
                }
                for (int i = 1; i <= numOfCards; i++)
                {
                    if (enforceRules)
                        sideboard.Add(CardDefLibrary.getCardByString(cardNameString, owner));
                    else
                        sideboard.Add(CardDefLibrary.getGenericCardByString(cardNameString, owner));
                }
            }
        }
        #endregion
    }
}
